package cn.iocoder.yudao.module.blog.service.follow;

import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
import cn.iocoder.yudao.module.blog.controller.app.follow.vo.AppBlogFollowPageReqVO;
import cn.iocoder.yudao.module.blog.controller.app.follow.vo.AppBlogFollowUnfollowReqVO;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.sun.net.httpserver.Authenticator;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import org.springframework.validation.annotation.Validated;

import java.util.*;
import java.util.function.Consumer;

import cn.iocoder.yudao.module.blog.controller.admin.follow.vo.*;
import cn.iocoder.yudao.module.blog.dal.dataobject.follow.BlogFollowDO;
import cn.iocoder.yudao.framework.common.pojo.PageResult;

import cn.iocoder.yudao.module.blog.convert.follow.BlogFollowConvert;
import cn.iocoder.yudao.module.blog.dal.mysql.follow.BlogFollowMapper;

import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.iocoder.yudao.module.blog.enums.ErrorCodeConstants.*;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.collection.ListUtil;

/**
 * 关注 Service 实现类
 *
 * @author 曹建伟
 */
@Service
@Validated
public class BlogFollowServiceImpl implements BlogFollowService {

    @Resource
    private BlogFollowMapper followMapper;

    @Override
    public Long createFollow(BlogFollowCreateReqVO createReqVO) {
        BlogFollowDO dbFollow = followMapper.selectOne(new LambdaQueryWrapperX<BlogFollowDO>()
                .eq(BlogFollowDO::getMemberId, createReqVO.getMemberId())
                .eq(BlogFollowDO::getFollowMemberId, createReqVO.getFollowMemberId()));

        Long id;
        if(dbFollow == null){
            // 插入
            BlogFollowDO follow = BlogFollowConvert.INSTANCE.convert(createReqVO);
            followMapper.insert(follow);
            id = follow.getId();
        }else {
            id = dbFollow.getId();
            dbFollow.setDeleted(false);
            followMapper.updateById(dbFollow);
        }

        // 返回
        return id;
    }

    @Override
    public void updateFollow(BlogFollowUpdateReqVO updateReqVO) {
        // 校验存在
        validateFollowExists(updateReqVO.getId());
        // 更新
        BlogFollowDO updateObj = BlogFollowConvert.INSTANCE.convert(updateReqVO);
        followMapper.updateById(updateObj);
    }

    @Override
    public void unFollow(AppBlogFollowUnfollowReqVO reqVO) {
        BlogFollowDO dbFollow = followMapper.selectOne(new LambdaQueryWrapperX<BlogFollowDO>()
                .eq(BlogFollowDO::getMemberId, reqVO.getMemberId())
                .eq(BlogFollowDO::getFollowMemberId, reqVO.getFollowMemberId()));

        // 先这样吧，不然需要手动 sql语句
        if(dbFollow != null){
            followMapper.deleteById(dbFollow.getId());
        }
    }

    @Override
    public void deleteFollow(Long id) {
        // 校验存在
        validateFollowExists(id);
        // 删除
        followMapper.deleteById(id);
    }

    private void validateFollowExists(Long id) {
        if (followMapper.selectById(id) == null) {
            throw exception(FOLLOW_NOT_EXISTS);
        }
    }

    @Override
    public BlogFollowDO getFollow(Long id) {
        return followMapper.selectById(id);
    }

    @Override
    public List<BlogFollowDO> getFollowList(Collection<Long> ids) {
        if (CollUtil.isEmpty(ids)) {
            return ListUtil.empty();
        }
        return followMapper.selectBatchIds(ids);
    }

    @Override
    public List<Long> getFollowList(Long memberId, Collection<Long> followedMemberIds){
        if(followedMemberIds.size() == 0){
            return new ArrayList<Long>();
        }

        LambdaQueryWrapperX<BlogFollowDO> wrapperX = new LambdaQueryWrapperX<>();
        wrapperX.eq(BlogFollowDO::getMemberId, memberId).in(BlogFollowDO::getFollowMemberId, followedMemberIds);

        List<BlogFollowDO> list = followMapper.selectList(wrapperX);

        List<Long> idList = new ArrayList<>();
        list.forEach(blogFollowDO -> {
            idList.add(blogFollowDO.getFollowMemberId());
        });

        return idList;
    }

    @Override
    public PageResult<BlogFollowDO> getFollowPage(BlogFollowPageReqVO pageReqVO) {
        return followMapper.selectPage(pageReqVO);
    }

    @Override
    public PageResult<BlogFollowDO> getAppFollowPage(AppBlogFollowPageReqVO pageReqVO) {
        return followMapper.selectPage(pageReqVO);
    }

    @Override
    public List<BlogFollowDO> getFollowList(BlogFollowExportReqVO exportReqVO) {
        return followMapper.selectList(exportReqVO);
    }

}
